package com.fan.shop.views.bean;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;

import org.apache.log4j.Logger;

import com.fan.shop.businesslogic.StockReqCancelProcess;
import com.fan.shop.businesslogic.StockReqCompleteProce;
import com.fan.shop.businesslogic.StockReqCreateProcess;
import com.fan.shop.businesslogic.StockReqFinaliseProcess;
import com.fan.shop.businesslogic.StockReqLineDeleteProcess;
import com.fan.shop.businesslogic.StockReqUpdateProcess;
import com.fan.shop.domain.Item;
import com.fan.shop.domain.StockReq;
import com.fan.shop.domain.StockReqLine;
import com.fan.shop.global.ShopGlobalVariables;
import com.fan.shop.model.commonbrowser.CommonBrowser;
import com.fan.shop.model.userclass.StockReqLineUserClass;
import com.fan.shop.services.ItemService;
import com.fan.shop.services.StockReqLineService;
import com.fan.shop.services.StockReqService;
import com.fan.shop.services.StockService;
import com.fan.shop.services.StoreService;
import com.fan.shop.services.TransactionReferenceService;
import com.fan.shop.services.UserService;

@ManagedBean(name = "stockReqBean")
@RequestScoped
public class StockReqBean extends ShopBean {

	private static Logger logger = Logger.getLogger(StockReqBean.class);

	private String requisitionNo;

	@ManagedProperty(value = "#{stockReqLineService}")
	private StockReqLineService stockReqLineService;

	@ManagedProperty(value = "#{stockReqService}")
	private static StockReqService stockReqService;

	@ManagedProperty(value = "#{transactionReferenceService}")
	private TransactionReferenceService transactionReferenceService;

	@ManagedProperty(value = "#{itemService}")
	private ItemService itemService;

	@ManagedProperty(value = "#{userService}")
	private UserService userService;

	@ManagedProperty(value = "#{storeService}")
	private StoreService storeService;
	
	@ManagedProperty(value = "#{stockService}")
	private StockService stockService;

	private String officerCode;
	private String storeCode;
	private Date transactionDate;
	private String transactionCode;
	private String status;
	private BigDecimal postage;
	private String comment;

	private int mode;

	private static Map<String, Item> itemsMap = new HashMap<String, Item>();
	private List<String> selectedItemCodes = new ArrayList<String>();

	private static List<StockReqLineUserClass> attachedLines = new ArrayList<StockReqLineUserClass>();

	public StockReqBean() {
		super();
		setReturnedValues();
	}

	public void setReturnedValues() {
		Map<String, Object> map = FacesContext.getCurrentInstance()
				.getExternalContext().getRequestMap();
		if (map.containsKey("common_browser")) {
			CommonBrowser commonBrowser = (CommonBrowser) map
					.get("common_browser");

			itemService = ((StockReqBean) commonBrowser.getCaller())
					.getItemService();
			userService = ((StockReqBean) commonBrowser.getCaller())
					.getUserService();
			storeService = ((StockReqBean) commonBrowser.getCaller())
					.getStoreService();
			transactionReferenceService = ((StockReqBean) commonBrowser
					.getCaller()).getTransactionReferenceService();

			stockReqService = ((StockReqBean) commonBrowser.getCaller())
					.getStockReqService();

			stockReqLineService = ((StockReqBean) commonBrowser.getCaller())
					.getStockReqLineService();

			requisitionNo = ((StockReqBean) commonBrowser.getCaller()).getRequisitionNo();
			officerCode = ((StockReqBean) commonBrowser.getCaller()).getOfficerCode();
			storeCode = ((StockReqBean) commonBrowser.getCaller()).getStoreCode();
			transactionCode = ((StockReqBean) commonBrowser.getCaller()).getTransactionCode();
			transactionDate = ((StockReqBean) commonBrowser.getCaller()).getTransactionDate(); 
			postage = ((StockReqBean) commonBrowser.getCaller()).getPostage();
			status = ((StockReqBean) commonBrowser.getCaller()).getStatus();
			comment = ((StockReqBean) commonBrowser.getCaller()).getComment();
			if (commonBrowser.getReturnList().size() == 0) {
				return;
			}

			if (commonBrowser.getTriggerField().equals("officer_code")) {
				officerCode = commonBrowser.getReturnList().get(0);

			}
			if (commonBrowser.getTriggerField().equals("store_code")) {
				storeCode = commonBrowser.getReturnList().get(0);
			}
			if (commonBrowser.getTriggerField().equals("transaction_code")) {
				transactionCode = commonBrowser.getReturnList().get(0);
			}
			if (commonBrowser.getTriggerField().equals("item_code")) {
				selectedItemCodes = commonBrowser.getReturnList();

				for (String item_code : selectedItemCodes) {
					if (!itemsMap.containsKey(item_code)) {
						itemsMap.put(item_code, itemService.getItem(item_code));
						StockReqLineUserClass stockReqLineUserClass = new StockReqLineUserClass();
						stockReqLineUserClass.setRequisitionNo(requisitionNo);
						stockReqLineUserClass.setItemCode(item_code);
//						stockReqLineUserClass
//								.setLineStatus(ShopGlobalVariables.ENTERING);
						stockReqLineUserClass.setPrice(new BigDecimal(0.0));
						stockReqLineUserClass.setQty(0);
						stockReqLineUserClass.setTransactionDate(new Date(
								System.currentTimeMillis()));
						// stockReqLineUserClass.setOfficerCode(userService.getCurrentUser().getUsername());
						if (requisitionNo == null
								|| requisitionNo.trim().length() == 0) {
							stockReqLineUserClass.setStoreCode("");
							stockReqLineUserClass.setOfficerCode("");
						} else {
							stockReqLineUserClass.setStoreCode(stockReqService
									.getStockReq(requisitionNo).getStoreCode());
							stockReqLineUserClass
									.setOfficerCode(stockReqService
											.getStockReq(requisitionNo)
											.getOfficerCode());
						}

						attachedLines.add(stockReqLineUserClass);

					}
				}

			}

		}
	}

	public void loadStockReqDetails() {
		if (requisitionNo != null && requisitionNo.trim().length() > 0) {
			StockReq stockReq = stockReqService.getStockReq(requisitionNo);
			officerCode = stockReq.getOfficerCode();
			storeCode = stockReq.getStoreCode();
			transactionCode = stockReq.getTransactionCode();
			transactionDate = stockReq.getTransactionDate();
			postage = stockReq.getPostage();
			status = stockReq.getStatus();
			comment = stockReq.getComment();

			List<StockReqLine> stockReqLines = stockReqService
					.getStockReqLines(requisitionNo);
			attachedLines.clear();
			itemsMap.clear();
			for (StockReqLine line : stockReqLines) {
				StockReqLineUserClass lineUserClass = (StockReqLineUserClass) stockReqLineService
						.copy(line);
				attachedLines.add(lineUserClass);
				itemsMap.put(line.getId().getItemCode(), itemService.getItem(line.getId().getItemCode()));
			}
		}
	}

	public String getRequisitionNo() {
		return requisitionNo;
	}

	public void setRequisitionNo(String requisitionNo) {

		this.requisitionNo = requisitionNo;
	}

	public String getOfficerCode() {
		return officerCode;
	}

	public void setOfficerCode(String officerCode) {
		this.officerCode = officerCode;
	}

	public String getStoreCode() {
		return storeCode;
	}

	public void setStoreCode(String storeCode) {
		this.storeCode = storeCode;
	}

	public Date getTransactionDate() {
		return transactionDate;
	}

	public void setTransactionDate(Date transactionDate) {
		this.transactionDate = transactionDate;
	}

	public String getTransactionCode() {
		return transactionCode;
	}

	public void setTransactionCode(String transactionCode) {
		this.transactionCode = transactionCode;
	}

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	public BigDecimal getPostage() {
		return postage;
	}

	public void setPostage(BigDecimal postage) {
		this.postage = postage;
	}

	public String getComment() {
		return comment;
	}

	public void setComment(String comment) {
		this.comment = comment;
	}

	public int getMode() {
		if (requisitionNo != null && requisitionNo.trim().length() > 0) {
			mode = ShopGlobalVariables.EDIT_MODE;
		} else {
			mode = ShopGlobalVariables.NEW_MODE;
		}
		return mode;
	}

	public void setMode(int mode) {
		this.mode = mode;
	}

	public static Logger getLogger() {
		return logger;
	}

	public static void setLogger(Logger logger) {
		StockReqBean.logger = logger;
	}

	public StockReqLineService getStockReqLineService() {
		return stockReqLineService;
	}

	public void setStockReqLineService(StockReqLineService stockReqLineService) {
		this.stockReqLineService = stockReqLineService;
	}

	public StockReqService getStockReqService() {
		return stockReqService;
	}

	public StockService getStockService() {
		return stockService;
	}

	public void setStockService(StockService stockService) {
		this.stockService = stockService;
	}

	@SuppressWarnings("static-access")
	public void setStockReqService(StockReqService stockReqService) {
		// first time load
		// if (this.stockReqService == null || stockReqService != null) {
		// attachedLines.clear();
		// itemsMap.clear();
		// // loadStockReqDetails();
		// List<StockReqLine> list = stockReqService
		// .getStockReqLines(requisitionNo);
		// for (StockReqLine stockReqLine : list) {
		// attachedLines.add((StockReqLineUserClass) stockReqService
		// .copy(stockReqLine));
		// }
		// }
		this.stockReqService = stockReqService;
	}

	public TransactionReferenceService getTransactionReferenceService() {
		return transactionReferenceService;
	}

	public void setTransactionReferenceService(
			TransactionReferenceService transactionReferenceService) {
		this.transactionReferenceService = transactionReferenceService;
	}

	public ItemService getItemService() {
		return itemService;
	}

	public void setItemService(ItemService itemService) {
		this.itemService = itemService;

	}

	public UserService getUserService() {
		return userService;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	public StoreService getStoreService() {
		return storeService;
	}

	public void setStoreService(StoreService storeService) {
		this.storeService = storeService;
	}

	public List<StockReqLineUserClass> getAttachedLines() {
		return attachedLines;
	}

	@SuppressWarnings("static-access")
	public void setAttachedLines(List<StockReqLineUserClass> attachedLines) {
		this.attachedLines = attachedLines;
	}

	public Map<String, Item> getItemsMap() {
		return itemsMap;
	}

	@SuppressWarnings("static-access")
	public void setItemsMap(Map<String, Item> itemsMap) {
		this.itemsMap = itemsMap;
	}

	public List<String> getSelectedItemCodes() {
		return selectedItemCodes;
	}

	public void setSelectedItemCodes(List<String> selectedItemCodes) {
		this.selectedItemCodes = selectedItemCodes;
	}

	public String openUsersAction() {
		CommonBrowser commonBrowser = new CommonBrowser();
		commonBrowser.setTriggerField("officer_code");
		commonBrowser.setParentPage("../../views/management/stock_req.faces");
		commonBrowser.setSelectionMode("single");
		commonBrowser.setShopService(userService);
//		commonBrowser.setSourceMap(buildPageMap());
		commonBrowser.setCaller(this);
		FacesContext.getCurrentInstance().getExternalContext().getRequestMap()
				.put("common_browser", commonBrowser);
		return "../../views/commonbrowser/commonbrowser.faces";

	}

	public String openStoresAction() {
		CommonBrowser commonBrowser = new CommonBrowser();
		commonBrowser.setTriggerField("store_code");
		commonBrowser.setParentPage("../../views/management/stock_req.faces");
		commonBrowser.setSelectionMode("single");
		commonBrowser.setShopService(storeService);
//		commonBrowser.setSourceMap(buildPageMap());
		commonBrowser.setCaller(this);
		FacesContext.getCurrentInstance().getExternalContext().getRequestMap()
				.put("common_browser", commonBrowser);
		return "../../views/commonbrowser/commonbrowser.faces";

	}

	public String openTransactionReferencesAction() {
		CommonBrowser commonBrowser = new CommonBrowser();
		commonBrowser.setTriggerField("transaction_code");
		commonBrowser.setParentPage("../../views/management/stock_req.faces");
		commonBrowser.setSelectionMode("single");
		transactionReferenceService
				.setGroupCode(ShopGlobalVariables.STOCK_RQUISITION_GROUP);
		commonBrowser.setShopService(transactionReferenceService);
//		commonBrowser.setSourceMap(buildPageMap());
		commonBrowser.setCaller(this);
		FacesContext.getCurrentInstance().getExternalContext().getRequestMap()
				.put("common_browser", commonBrowser);
		return "../../views/commonbrowser/commonbrowser.faces";

	}

	public String openItemsAction() {
		CommonBrowser commonBrowser = new CommonBrowser();
		commonBrowser.setTriggerField("item_code");
		commonBrowser.setParentPage("../../views/management/stock_req.faces");
		commonBrowser.setSelectionMode("multi");
		commonBrowser.setShopService(itemService);
//		commonBrowser.setSourceMap(buildPageMap());
		commonBrowser.setCaller(this);
		FacesContext.getCurrentInstance().getExternalContext().getRequestMap()
				.put("common_browser", commonBrowser);
		return "../../views/commonbrowser/commonbrowser.faces";

	}

//	public Map<String, Object> buildPageMap() {
//		Map<String, Object> map = new HashMap<String, Object>();
//		map.put("requisition_no", requisitionNo);
//		map.put("officer_code", officerCode);
//		map.put("store_code", storeCode);
//		map.put("transaction_code", transactionCode);
//		if (transactionDate == null) {
//			transactionDate = new Date();
//		}
//		map.put("transaction_date", transactionDate);
//		map.put("postage", postage);
//		map.put("status", status);
//		map.put("comment", comment);
//		return map;
//	}

	public String saveItemsAction() {
		return "stock_req.faces";
	}

	public String saveStockReqAction() {
		if (getMode() == ShopGlobalVariables.NEW_MODE) {
			createNewStockReq();
		} else {
			editNewStockReq();
		}

		return "stock_req.faces";
	}

	private void createNewStockReq() {
		StockReqCreateProcess stockReqCreateProcess = new StockReqCreateProcess();
		stockReqCreateProcess.setRequisitionNo(requisitionNo);
		stockReqCreateProcess.setAttachedLines(attachedLines);
		stockReqCreateProcess.setComment(comment);
		stockReqCreateProcess.setOfficerCode(officerCode);
		stockReqCreateProcess.setPostage(postage);
		stockReqCreateProcess.setStatus(ShopGlobalVariables.ENTERING);
		stockReqCreateProcess.setStockReqLineService(stockReqLineService);
		stockReqCreateProcess.setStockReqService(stockReqService);
		stockReqCreateProcess.setStoreCode(storeCode);
		stockReqCreateProcess.setStoreService(storeService);
		stockReqCreateProcess.setTransactionCode(transactionCode);
//		stockReqCreateProcess.setTransactionDate(transactionDate);
		stockReqCreateProcess
				.setTransactionReferenceService(transactionReferenceService);
		stockReqCreateProcess.setUserService(userService);
		int result = stockReqCreateProcess.process();
		if (result == ShopGlobalVariables.FAILED) {
			logger.error("Create Stock Req Failed: "
					+ stockReqCreateProcess.getErrorMessage());
		}
		requisitionNo = stockReqCreateProcess.getRequisitionNo();

		loadStockReqDetails();

	}

	private void editNewStockReq() {

		StockReqUpdateProcess stockReqUpdateProcess = new StockReqUpdateProcess();
		stockReqUpdateProcess.setRequisitionNo(requisitionNo);
		stockReqUpdateProcess.setAttachedLines(attachedLines);
		stockReqUpdateProcess.setComment(comment);
		stockReqUpdateProcess.setOfficerCode(officerCode);
		stockReqUpdateProcess.setPostage(postage);
		stockReqUpdateProcess.setStatus(ShopGlobalVariables.ENTERING);
		stockReqUpdateProcess.setStockReqLineService(stockReqLineService);
		stockReqUpdateProcess.setStockReqService(stockReqService);
		stockReqUpdateProcess.setStoreCode(storeCode);
		stockReqUpdateProcess.setStoreService(storeService);
		stockReqUpdateProcess.setUserService(userService);

		int result = stockReqUpdateProcess.process();
		if (result == ShopGlobalVariables.FAILED) {
			logger.error("Update Stock Req Failed: "
					+ stockReqUpdateProcess.getErrorMessage());
		}

		requisitionNo = stockReqUpdateProcess.getRequisitionNo();

	}

	public String removeStockReqLineAction(String lineItemCode) {
		if (lineItemCode != null) {
			if (itemsMap.containsKey(lineItemCode)) {
				itemsMap.remove(lineItemCode);
				int index = -1;
				for (int i = 0; i < attachedLines.size(); i++) {
					StockReqLineUserClass stockReqLineUserClass = attachedLines
							.get(i);
					if (stockReqLineUserClass.getItemCode()
							.equals(lineItemCode)) {
						index = i;

						StockReqLineDeleteProcess stockReqLineDeleteProcess = new StockReqLineDeleteProcess();
						stockReqLineDeleteProcess
								.setRequisitionNo(requisitionNo);
						stockReqLineDeleteProcess
								.setItemCode(stockReqLineUserClass.getItemCode());
						stockReqLineDeleteProcess
								.setStockReqLineService(stockReqLineService);
						int result = stockReqLineDeleteProcess.process();
						if (result == ShopGlobalVariables.FAILED) {
							attachedLines.remove(index);
							return "stock_req.faces";
						}
						break;
					}
				}
				attachedLines.remove(index);
			}
		}
		logger.info(lineItemCode);
		return "stock_req.faces";
	}

	public String completeStockReqAction() {

		StockReqCompleteProce stockReqCompleteProce = new StockReqCompleteProce();
		stockReqCompleteProce.setRequisitionNo(requisitionNo);
		stockReqCompleteProce.setComment(comment);
		stockReqCompleteProce.setPostage(postage);
		stockReqCompleteProce.setStatus(ShopGlobalVariables.POSTED);
		stockReqCompleteProce.setStockReqService(stockReqService);
		stockReqCompleteProce.setStockReqLineService(stockReqLineService);
		stockReqCompleteProce.setAttachedLines(attachedLines);

		int result = stockReqCompleteProce.process();
		if (result == ShopGlobalVariables.FAILED) {
			return null;
		}

		requisitionNo = stockReqCompleteProce.getRequisitionNo();
		loadStockReqDetails();
		return "stock_req.faces";
	}

	public String finaliseStockReqAction() {
		StockReqFinaliseProcess stockReqFinaliseProcess = new StockReqFinaliseProcess();
		stockReqFinaliseProcess.setRequisitionNo(requisitionNo);
		stockReqFinaliseProcess.setAttachedLines(attachedLines);
		stockReqFinaliseProcess.setComment(comment);
		stockReqFinaliseProcess.setPostage(postage);
		stockReqFinaliseProcess.setStockReqLineService(stockReqLineService);
		stockReqFinaliseProcess.setStockReqService(stockReqService);
		stockReqFinaliseProcess.setItemService(itemService);
		stockReqFinaliseProcess.setStoreService(storeService);
		stockReqFinaliseProcess.setStockService(stockService);

		int result = stockReqFinaliseProcess.process();
		if (result == ShopGlobalVariables.FAILED) {
			return null;
		}

		requisitionNo = stockReqFinaliseProcess.getRequisitionNo();
		loadStockReqDetails();
		return "stock_req.faces";
	}
	
	
	public String cancelStockReqAction() {
		
		StockReqCancelProcess stockReqCancelProcess = new StockReqCancelProcess();
		stockReqCancelProcess.setRequisitionNo(requisitionNo);
		stockReqCancelProcess.setAttachedLines(attachedLines);
		stockReqCancelProcess.setStockReqLineService(stockReqLineService);
		stockReqCancelProcess.setStockReqService(stockReqService);

		int result = stockReqCancelProcess.process();
		if (result == ShopGlobalVariables.FAILED) {
			return null;
		}

		requisitionNo = stockReqCancelProcess.getRequisitionNo();
		loadStockReqDetails();
		return "stock_req.faces";
	}
	

}
